﻿using DrawTools.Tools;
using DrawTools.Utils;
using LS.DicomViewer.Common;
using LS.DicomViewer.ViewModels;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Path = System.IO.Path;

namespace LS.DicomViewer
{
    /// <summary>
    /// DicomViewer.xaml 的交互逻辑
    /// </summary>
    public partial class DicomViewer : UserControl
    {
        private static readonly DependencyProperty FrameTimeProperty;
        private static readonly DependencyProperty PixelSpacingProperty;

        public double? FrameTime
        {
            get { return (double?)GetValue(FrameTimeProperty); }
            set { SetValue(FrameTimeProperty, value); }
        }

        public double? PixelSpacing
        {
            get { return (double?)GetValue(PixelSpacingProperty); }
            set { SetValue(PixelSpacingProperty, value); }
        }

        static DicomViewer()
        {
            FrameTimeProperty = DependencyProperty.Register(nameof(FrameTime), typeof(double?), typeof(DicomViewer));
            PixelSpacingProperty = DependencyProperty.Register(nameof(PixelSpacing), typeof(double?), typeof(DicomViewer));
        }

        #region 变量/属性

        public DicomViewModel ViewModel => Dispatcher.Invoke(() => this.mainPanel.DataContext as DicomViewModel);

        private static string dicom3DViewerPath;

        /// <summary>
        /// Dicom3D浏览工具目录
        /// </summary>
        public static string Dicom3DViewerPath
        {
            get
            {
                if (string.IsNullOrEmpty(dicom3DViewerPath))
                {
                    var runDir = Environment.CurrentDirectory;
                    dicom3DViewerPath = Path.Combine(runDir, @"3DViewer\LS.Dicom3DViewer.exe");
                }
                return dicom3DViewerPath;
            }
        }

        private static string DrawFolder
        {
            get
            {
                var folder = Path.Combine(Environment.CurrentDirectory, "Draws");
                if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
                return folder;
            }
        }

        private MyDictionary<int, string> drawDataCache = new MyDictionary<int, string>();

        /// <summary>
        /// 画图数据缓存,在画图完成切换当前帧时会保存在此
        /// </summary>
        public MyDictionary<int, string> DrawDataCache { get => drawDataCache; }


        public static readonly DependencyProperty ShowDrawToolbarProperty = DependencyProperty.Register("ShowDrawToolbar", typeof(bool), typeof(DicomViewer), new PropertyMetadata(true, (a, e) => ((DicomViewer)a).ViewModel.ShowDrawToolbar = (bool)e.NewValue));

        /// <summary>
        /// 是否显示操作工具栏
        /// </summary>
        public bool ShowDrawToolbar
        {
            get => (bool)this.GetValue(ShowDrawToolbarProperty);
            set => this.SetValue(ShowDrawToolbarProperty, value);
        }

        public static readonly DependencyProperty ShowPlayToolbarProperty = DependencyProperty.Register("ShowPlayToolbar", typeof(bool), typeof(DicomViewer), new PropertyMetadata(true, (a, e) => ((DicomViewer)a).ViewModel.ShowPlayToolbar = (bool)e.NewValue));

        /// <summary>
        /// 是否显示播放工具栏
        /// </summary>
        public bool ShowPlayToolbar
        {
            get => (bool)this.GetValue(ShowPlayToolbarProperty);
            set => this.SetValue(ShowPlayToolbarProperty, value);
        }

        public static readonly DependencyProperty Show3DButtonProperty = DependencyProperty.Register("Show3DButton", typeof(bool), typeof(DicomViewer), new PropertyMetadata(true,
            (a, e) =>
            ((DicomViewer)a).ViewModel.Show3DButton = (bool)e.NewValue)
            );

        /// <summary>
        /// 是否显示3D操作按钮
        /// </summary>
        public bool Show3DButton
        {
            get => (bool)this.GetValue(Show3DButtonProperty);
            set => this.SetValue(Show3DButtonProperty, value);
        }

        public static readonly DependencyProperty DicomFileProperty = DependencyProperty.Register("DicomFile", typeof(string), typeof(DicomViewer), new PropertyMetadata(string.Empty,
            (a, e) =>
            {
                if (e.NewValue == null || e.NewValue.Equals(string.Empty)) return;
                var view = (DicomViewer)a;
                lock (view)
                {
                    view.LoadDicomFile(e.NewValue.ToString()).Wait();
                }
                view.DicomFileChangedAction?.Invoke(e.NewValue.ToString());
            }
            ));

        public Action<string> DicomFileChangedAction { get; set; }

        /// <summary>
        /// Dicom文件
        /// </summary>
        public string DicomFile
        {
            get => (string)this.GetValue(DicomFileProperty);
            set => this.SetValue(DicomFileProperty, value);
        }

        public static readonly DependencyProperty ZoomProperty = DependencyProperty.Register("Zoom", typeof(double), typeof(DicomViewer), new PropertyMetadata(1.0,
          (a, e) =>
          {
              if (e.NewValue == null) return;
              var view = (DicomViewer)a;
              view.drawCanvas.Zoom = (double)e.NewValue;
          }
          ));

        /// <summary>
        /// Dicom浏览区域的缩放比率
        /// </summary>
        public double Zoom
        {
            get => (double)this.GetValue(ZoomProperty);
            set => this.SetValue(ZoomProperty, value);
        }

        /// <summary>
        /// 3D显示时，左边影像文件全路径
        /// </summary>
        public string LeftImagePath { get; set; }

        /// <summary>
        /// 3D显示时，右边影像文件全路径
        /// </summary>
        public string RightImagePath { get; set; }

        /// <summary>
        /// 3D浏览截图触发的事件
        /// </summary>
        public Action<IEnumerable<string>> View3DCutImagesAction { get; set; }

        public static System.Windows.Media.Color? ToolBarColor { get; set; }

        /// <summary>
        /// dicom文件总帧数
        /// </summary>
        public int? FrameCount => ViewModel?.CurrentDicom?.NumberOfFrames;

        /// <summary>
        /// dicom是否在处理中
        /// </summary>
        public event Action<bool> IsBusyChanged;

        private Process p3d = null;

        #endregion 变量/属性

        /// <summary>
        /// </summary>
        public DicomViewer()
        {
            var dic = new ResourceDictionary();
            try
            {
                dic.Source = new Uri("pack://application:,,,/HandyControl;component/Themes/SkinDark.xaml");
                this.Resources.MergedDictionaries.Add(dic);
            }
            catch { }
            try
            {
                dic.Source = new Uri("pack://application:,,,/HandyControl;component/Themes/Theme.xaml");
                this.Resources.MergedDictionaries.Add(dic);
            }
            catch { }
            try
            {
                dic.Source = new Uri("pack://application:,,,/DrawTools;component/Themes/generic.xaml");
                this.Resources.MergedDictionaries.Add(dic);
            }
            catch { }

            InitializeComponent();

            DpiHelper.GetDpiFromVisual(Application.Current.MainWindow);

            color_picker.SelectedColorChanged += delegate { this.drawCanvas.Brush = color_picker.SelectedBrush; btn_color.IsChecked = false; };
            color_picker.Canceled += delegate { btn_color.IsChecked = false; };

            this.toolbar.AddHandler(RadioButton.CheckedEvent, new RoutedEventHandler(OnDrawToolChecked));

            this.Loaded += (a, b) =>
            {
                ViewModel.CurrentFrameIndexChanging += CurrentFrameIndexChanging;
                ViewModel.CurrentFrameIndexChanged += CurrentFrameIndexChanged;
                ViewModel.PropertyChanged += ViewModel_PropertyChanged;
                this.slider.SizeChanged += (c, d) => SilderTrack.SizeChanged += SilderTrack_SizeChanged;
                drawCanvas.DrawingToolType = drawToolType;
            };
            if (ToolBarColor != null)
            {
                this.toolbar.Background = new System.Windows.Media.SolidColorBrush(ToolBarColor.Value);
            }
            PixelRateDrawTool.SetPixelRateAction = () =>
            {
                var win = new SetPixelRateWindow();
                if (win.ShowDialog() == true)
                {
                    return win.Rate;
                }
                return 1;
            };
            this.Unloaded += DicomViewer_Unloaded;
#if DEBUG
            var source = PresentationSource.FromVisual(this);
            if (source?.CompositionTarget != null)
            {
                var dpiX = source.CompositionTarget.TransformToDevice.M11;
                Debug.WriteLine($"CompositionTargetRatio:{dpiX}");
            }
#endif           
        }

        private void slider_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            ViewModel.StopCommand.Execute();
        }

        public int? GetAge()
        {
            return ViewModel.GetAge();
        }

        public void Stop()
        {
            ViewModel.Reset();
        }

        private void LengthRateClick(object sender, RoutedEventArgs e)
        {
            if (this.drawCanvas.Visuals.Count == 0) return;
            LengthDrawTool firstTool = null, secondTool = null;
            for (int i = this.drawCanvas.Visuals.Count - 1; i >= 0; i--)
            {
                var tool = this.drawCanvas.Visuals[i];
                if (tool is LengthDrawTool rdl)
                {
                    if (firstTool == null) { firstTool = rdl; }
                    else { secondTool = rdl; }
                }
                if (secondTool != null)
                {
                    var firstValue = double.Parse(firstTool.Text.Replace("mm", string.Empty));// firstTool.GetValue();
                    var secondValue = double.Parse(secondTool.Text.Replace("mm", string.Empty)); //secondTool.GetValue();
                    var percent = 0.0;
                    if (secondValue > firstValue)
                    {
                        percent = (firstValue / secondValue * 100);
                    }
                    else
                    {
                        percent = (secondValue / firstValue * 100);
                    }
                    var s = secondTool.Index > 0 ? $"与{secondTool.Index})" : string.Empty;
                    var str = $"{firstTool.Index.ToString().PadLeft(2)}){s} 长度比：{string.Format("{0:f2}", percent)}%";
                    drawCanvas.AddTogetherText(str);
                    firstTool = secondTool = null;
                }
            }
        }

        private void AreaRateClick(object sender, RoutedEventArgs e)
        {
            if (this.drawCanvas.Visuals.Count == 0) return;
            AreaClosedLineDrawTool firstTool = null, secondTool = null;
            for (int i = this.drawCanvas.Visuals.Count - 1; i >= 0; i--)
            {
                var tool = this.drawCanvas.Visuals[i];
                if (tool is AreaClosedLineDrawTool dl)
                {
                    if (firstTool == null) { firstTool = dl; }
                    else { secondTool = dl; }
                }
                if (secondTool != null)
                {
                    var firstValue = firstTool.GetValue();
                    var secondValue = secondTool.GetValue();
                    var percent = 0.0;
                    if (secondValue > firstValue)
                    {
                        percent = (firstValue / secondValue * 100);
                    }
                    else
                    {
                        percent = (secondValue / firstValue * 100);
                    }

                    var s = secondTool.Index > 0 ? $"与{secondTool.Index})" : string.Empty;
                    var str = $"{firstTool.Index.ToString().PadLeft(2)}){s} 面积比：{string.Format("{0:f2}", percent)}%";
                    drawCanvas.AddTogetherText(str);
                    firstTool = secondTool = null;
                }
            }
        }
    }
}